package com.hzyl.famousreader.view.widget.core;

import com.blankj.utilcode.util.CloseUtils;

import java.io.BufferedInputStream;
import java.io.FileInputStream;

public class CharsetUtils {

  public static Charset getCharset(String fileName) {
    BufferedInputStream bis = null;
    Charset charset = Charset.GBK;
    byte[] first3Bytes = new byte[3];
    try {
      boolean checked = false;
      bis = new BufferedInputStream(new FileInputStream(fileName));
      bis.mark(0);
      int read = bis.read(first3Bytes, 0, 3);
      if (read == -1)
        return charset;
      if (first3Bytes[0] == (byte) 0xEF
        && first3Bytes[1] == (byte) 0xBB
        && first3Bytes[2] == (byte) 0xBF) {
        charset = Charset.UTF8;
        checked = true;
      }
            /*
             * 不支持 UTF16LE 和 UTF16BE
            else if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) {
                charset = Charset.UTF16LE;
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xFE
                    && first3Bytes[1] == (byte) 0xFF) {
                charset = Charset.UTF16BE;
                checked = true;
            } else */

      bis.mark(0);
      if (!checked) {
        while ((read = bis.read()) != -1) {
          if (read >= 0xF0)
            break;
          if (0x80 <= read && read <= 0xBF) // 单独出现BF以下的，也算是GBK
            break;
          if (0xC0 <= read && read <= 0xDF) {
            read = bis.read();
            if (0x80 <= read && read <= 0xBF) // 双字节 (0xC0 - 0xDF)
              // (0x80 - 0xBF),也可能在GB编码内
              continue;
            else
              break;
          } else if (0xE0 <= read && read <= 0xEF) {// 也有可能出错，但是几率较小
            read = bis.read();
            if (0x80 <= read && read <= 0xBF) {
              read = bis.read();
              if (0x80 <= read && read <= 0xBF) {
                charset = Charset.UTF8;
                break;
              } else
                break;
            } else
              break;
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      CloseUtils.closeIO(bis);
    }
    return charset;
  }
}
